#ifndef SEARCH_H_
#define SEARCH_H_

#include <glibmm.h>
#include <boost/shared_ptr.hpp>

#ifdef USE_MIGEMO
# include <migemo.h>
#endif

#include "conf/attribute.h"
#include "misc.h"
#include "options.h"

namespace gpyp {

class Application;
class Search;
typedef boost::shared_ptr<Search> RefSearch;

enum SearchType {
  SEARCHTYPE_NORMAL = 0,
  SEARCHTYPE_MIGEMO,
  SEARCHTYPE_REGEX,
};
class AttributeSearchType :
    public conf::AttributeEnum<SearchType, AttributeSearchType> {
  friend class conf::AttributeEnum<SearchType, AttributeSearchType>;
protected:
  static NameTable _name_table[];

public:
  SearchType next();

  inline AttributeSearchType(const Glib::ustring &name, SearchType defval) :
    conf::AttributeEnum<SearchType, AttributeSearchType>(name, defval)
  {
  }
};
typedef conf::RefAttributeEnum<AttributeSearchType> RefAttributeSearchType;

enum MigemoMode {
  MIGEMO_MODE_DISABLED = 0,
  MIGEMO_MODE_CMIGEMO,
  MIGEMO_MODE_MIGEMOSRV,
};
class AttributeMigemoMode :
    public conf::AttributeEnum<MigemoMode, AttributeMigemoMode> {
  friend class conf::AttributeEnum<MigemoMode, AttributeMigemoMode>;
protected:
  static NameTable _name_table[];

public:
  inline AttributeMigemoMode(const Glib::ustring &name, MigemoMode defval) :
    conf::AttributeEnum<MigemoMode, AttributeMigemoMode>(name, defval)
  {
  }
};
typedef conf::RefAttributeEnum<AttributeMigemoMode> RefAttributeMigemoMode;

class Conf;
class Search : public conf::Element {
private:
  sigc::signal<void> signal_changed_;
public:
  inline sigc::signal<void> signal_changed() {
    return signal_changed_;
  }

private:
  static sigc::signal<void> _signal_enable_migemo_changed;
public:
  inline static sigc::signal<void> signal_enable_migemo_changed() {
    return _signal_enable_migemo_changed;
  }

private:
  static Conf      *_conf;
  static MigemoMode _migemo_mode;
#ifdef USE_MIGEMO
  static migemo    *_migemo_obj;
#endif

public:
  static void init(Application &app);
  static void uninit();
  static bool migemo_usable();
  static Glib::ustring migemo_query(const Glib::ustring &str);

private:
  RefAttributeSearchType type_;

  Glib::ustring str_;
  RefRegex      re_;

  void recreate_re();

public:
  inline RefAttributeSearchType type() {
    return type_;
  }

  inline RefRegex get() {
    return re_;
  }
  void set(const Glib::ustring &str);

  inline const Glib::ustring &get_source() const {
    return str_;
  }

  inline bool empty() const {
    return !re_;
  }
  inline bool match(const Glib::ustring &str) const {
    return re_->match(str);
  }

  void convert_to_regex();

  Search(const Glib::ustring &name);
};

}/*gpyp*/

#endif/*SEARCH_H_*/
